package com.qzsoft.system.modules.zhjdlogin.dao;

import cn.hutool.core.date.DateUtil;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.stereotype.Repository;
import org.springframework.util.CollectionUtils;

@Repository
public class PasswordValidDao {
    
    @Autowired
    private JdbcTemplate jdbcTemplate;
    
    @Value("${password-validation.expireDate}")
    private Integer expireDate;
    
    @Value("${password-validation.complexity}")
    private String complexity;
    
    @Value("${password-validation.min-length}")
    private Integer minLength;
    
    @Value("${password-validation.max-length}")
    private Integer maxLength;
    
    private final int successCode = 200;
    
    private final int errorCode = 107;
    
    private final String expireTip = "密码已过期，请重设密码";
    
    private final String invalidateTip = "密码过于简单，请重设密码";
    
    private final String successTip = "success";

    public Map<String, Object> validatePasswordAfterLoginSuccess(Object userId, String password) {
        Map<String, Object> returnMap = createReturnMap();
        if (validatePassword(password, returnMap)) {
            return returnMap;
        }
        if (this.expireDate != null) {
            List<Map<String, Object>> list = queryPasswordExpireTime(userId);
            if (CollectionUtils.isEmpty(list)) {
                insertPasswordExpireTime(userId);
            } else if (DateUtil.now().compareTo(((Map) list.get(0)).get("expire_date").toString()) >= 0) {
                returnMap.put("code", errorCode);
                returnMap.put("msg", expireTip);
                return returnMap;
            }
        }
        return returnMap;
    }

    public Map<String, Object> validateResetPassword(Object userId, String password) {
        Map<String, Object> returnMap = createReturnMap();
        if (validatePassword(password, returnMap)) {
            return returnMap;
        }
        if (this.expireDate != null) {
            resetPasswordExpireTime(userId);
        }
        return returnMap;
    }

    public void resetPasswordExpireTime(Object userId) {
        List<Map<String, Object>> list = queryPasswordExpireTime(userId);
        if (CollectionUtils.isEmpty(list)) {
            insertPasswordExpireTime(userId);
        } else {
            updatePasswordExpireTime(userId);
        }
    }

    public boolean validatePassword(String password, Map<String, Object> returnMap) {
        Boolean lengthCheck = Boolean.valueOf(true);
        Boolean numberCheck = Boolean.valueOf(true);
        Boolean alphabetCheck = Boolean.valueOf(true);
        Boolean wWalphabetCheck = Boolean.valueOf(true);
        Boolean symbolCheck = Boolean.valueOf(true);
        if ((this.minLength != null) && (password.length() < this.minLength.intValue())) {
            lengthCheck = Boolean.valueOf(false);
        }
        if ((this.maxLength != null) && (password.length() > this.maxLength.intValue())) {
            lengthCheck = Boolean.valueOf(false);
        }
        if (StringUtils.isNotBlank(this.complexity)) {
            String[] complexitys = this.complexity.trim().split(",");
            for (int i = 0; i < complexitys.length; i++) {
                String compleityItem = complexitys[i];
                switch (compleityItem) {
                case "1":
                    numberCheck = Boolean.valueOf(Pattern.matches(".*[0-9].*", password));
                    break;
                case "2":
                    alphabetCheck = Boolean.valueOf(Pattern.matches("(.*[a-zA-Z].*)", password));
                    break;
                case "3":
                    wWalphabetCheck = Boolean.valueOf(
                            (Pattern.matches("(.*[a-z].*)", password)) && (Pattern.matches("(.*[A-Z].*)", password)));
                    break;
                case "4":
                    Pattern reges = Pattern.compile("[$&+,:;=?@#|'<>.^*()%!-]");
                    Matcher matcher = reges.matcher(password);
                    if (!matcher.find()) {
                        symbolCheck = Boolean.valueOf(false);
                    }
                    break;
                }
            }
        }
        if ((!numberCheck.booleanValue()) || (!lengthCheck.booleanValue()) || (!alphabetCheck.booleanValue())
                || (!wWalphabetCheck.booleanValue()) || (!symbolCheck.booleanValue())) {
            returnMap.put("code", errorCode);
            returnMap.put("msg", invalidateTip);
            return true;
        }
        return false;
    }

    private List<Map<String, Object>> queryPasswordExpireTime(Object userId) {
        StringBuilder strSql = new StringBuilder();
        strSql.append(" SELECT * from sys_user_password_update_time where user_id = '").append(userId).append("'");
        return this.jdbcTemplate.queryForList(strSql.toString());
    }

    private void insertPasswordExpireTime(Object userId) {
        this.jdbcTemplate.update("insert into sys_user_password_update_time(user_id,expire_date) values ('" + userId
                + "','" + DateUtil.offsetDay(new Date(), this.expireDate.intValue()) + "')");
    }

    private void updatePasswordExpireTime(Object userId) {
        this.jdbcTemplate.update("update sys_user_password_update_time set expire_date = '"
                + DateUtil.offsetDay(new Date(), this.expireDate.intValue()) + "' where user_id = '" + userId + "'");
    }

    public Map<String, Object> createReturnMap() {
        Map<String, Object> returnMap = new HashMap();
        returnMap.put("code", successCode);
        returnMap.put("msg", successTip);
        return returnMap;
    }
}
